package com.seguriapp.complaints.gwt.server;

import static com.google.common.collect.Lists.newArrayList;

import java.util.List;

import net.customware.gwt.dispatch.server.ExecutionContext;
import net.customware.gwt.dispatch.shared.DispatchException;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.restlet.resource.ClientResource;

import com.seguriapp.common.config.GlobalConfigLoader;
import com.seguriapp.common.gwt.server.AbstractSeguriAppHandler;
import com.seguriapp.common.security.SeguriAppUser;
import com.seguriapp.complaints.gwt.shared.GetPoliceStationListAction;
import com.seguriapp.complaints.gwt.shared.GetPoliceStationListResult;
import com.seguriapp.entities.SeguriAppEntity;
import com.seguriapp.entities.User;

public class GetPoliceStationListHandler extends AbstractSeguriAppHandler<GetPoliceStationListAction, GetPoliceStationListResult> {

  private static final Logger LOGGER = Logger.getLogger(GetPoliceStationListHandler.class);

  public Class<GetPoliceStationListAction> getActionType() {
    return GetPoliceStationListAction.class;
  }

  public GetPoliceStationListResult execute(final GetPoliceStationListAction action, final ExecutionContext context) throws DispatchException {
    final GetPoliceStationListResult result = new GetPoliceStationListResult();
    try {
      final String url = GlobalConfigLoader.getInstance().getGlobalConfig().getBackEndUrl()
          .concat(GlobalConfigLoader.getInstance().getGlobalConfig().getGetEntitesListByCategories());
      final ClientResource resource = new ClientResource(url);
      final String policeStationListJs = resource.post(convertDataToJsonString(action)).getText();
      result.setPoliceStationList(getJsonDataFromString(policeStationListJs));
    } catch (Exception e) {
      LOGGER.error("Error getting the police station list", e);
    }
    return result;
  }

  private String convertDataToJsonString(final GetPoliceStationListAction action) {
    final JSONObject obj = new JSONObject();
    try {
      obj.put("categoriesList", "1");
      if (action.isSearch()) {
        final User user = SeguriAppUser.getSeguriAppSecureUser() != null ? SeguriAppUser.getSeguriAppSecureUser().getSeguriAppUser() : null;
        if (user != null) {
          obj.put("userId", user.getId());
        }
      }
    } catch (JSONException e) {
      LOGGER.error("Error al convertir parametros de busqueda a json", e);
    }
    LOGGER.info("Sending Data : \n" + obj.toString());
    return obj.toString();
  }

  private List<SeguriAppEntity> getJsonDataFromString(final String crimeCategoryListJs) {
    LOGGER.info("Receiving Data : \n" + crimeCategoryListJs);
    final List<SeguriAppEntity> policeStationList = newArrayList();
    final JSONObject root = JSONObject.fromObject(crimeCategoryListJs);
    JSONArray dataArray = null;
    JSONObject jo = null;
    if (root.has("entitiesList")) {
      dataArray = root.getJSONArray("entitiesList");
      if (dataArray != null) {
        for (int i = 0; i < dataArray.size(); i++) {
          jo = dataArray.getJSONObject(i);
          final SeguriAppEntity policeStation = processjSONObject(jo);
          if (policeStation != null) {
            policeStationList.add(policeStation);
          }
        }
      }
    }
    return policeStationList;
  }

  private SeguriAppEntity processjSONObject(final JSONObject jo) {
    if (jo.has("id") && jo.has("title") && jo.has("latitude") && jo.has("longitude")) {
      final SeguriAppEntity policeStation = new SeguriAppEntity();
      policeStation.setId(jo.getLong("id"));
      policeStation.setTitle(jo.getString("title"));
      policeStation.setLatitude(jo.getDouble("latitude"));
      policeStation.setLongitude(jo.getDouble("longitude"));
      return policeStation;
    }
    return null;
  }

}
